/*
 *    Copyright (c) 2018-2025, proj All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the proj developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: proj
 */

package com.ykht.proj.coupon.controller;

import cn.hutool.json.JSONUtil;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ykht.proj.activity.api.feign.RemoteBrandAgreementService;
import com.ykht.proj.activity.entity.VBrandAgreement;
import com.ykht.proj.common.core.util.R;
import com.ykht.proj.common.log.annotation.SysLog;
import com.ykht.proj.common.security.util.SecurityUtils;
import com.ykht.proj.coupon.Enum.DisplayEnum;
import com.ykht.proj.coupon.Enum.StatusEnum;
import com.ykht.proj.coupon.Enum.UserTypeEnum;
import com.ykht.proj.coupon.entity.CnBrand;
import com.ykht.proj.coupon.entity.CnCompany;
import com.ykht.proj.coupon.entity.CnLabel;
import com.ykht.proj.coupon.entity.CnShop;
import com.ykht.proj.coupon.service.CnBrandService;
import com.ykht.proj.coupon.service.CnCompanyService;
import com.ykht.proj.coupon.service.CnLabelService;
import com.ykht.proj.coupon.service.CnShopService;
import com.ykht.proj.coupon.vo.BindedBrandUserByLoginIdVo;
import com.ykht.proj.coupon.vo.CnBrandVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * 品牌表
 *
 * @author proj code generator
 * @date 2020-11-16 17:00:21
 */
@RestController
@AllArgsConstructor
@RequestMapping("/cnbrand")
@Api(value = "cnbrand", tags = "品牌表管理")
@Slf4j
public class CnBrandController {

	private final CnBrandService cnBrandService;

	private final CnLabelService cnLabelService;

	private final CnCompanyService cnCompanyService;

	private final CnShopService cnShopService;
	private final RemoteBrandAgreementService remoteBrandAgreementService;

	/**
	 * 分页查询
	 *
	 * @param page      分页对象
	 * @param cnBrandVo 品牌表
	 * @return
	 */
	@ApiOperation(value = "分页查询", notes = "分页查询")
	@GetMapping("/page")
	public R getCnBrandPage(Page page, CnBrandVo cnBrandVo) {
		log.info("->根据角色类型 获取后台的品牌列表 分页查询:{}", JSONUtil.toJsonStr(cnBrandVo));
		return cnBrandService.queryPage(page, cnBrandVo);
	}

	@ApiOperation(value = "根据公司id查询", notes = "根据公司id查询")
	@PostMapping("/getByCompany")
//	@PreAuthorize("@pms.hasPermission('coupon_cnbrand_view')" )
	public R getByCompany(@RequestBody CnBrandVo cnBrandVo) {
		Map<String, Object> map = new HashMap<>();
		map.put("del_flag", 0);
		map.put("company_id", cnBrandVo.getCompanyId());
		return R.ok(cnBrandService.listByMap(map));
	}


	/**
	 * 通过id查询品牌表
	 *
	 * @param id id
	 * @return R
	 */
	@ApiOperation(value = "通过id查询", notes = "通过id查询")
	@GetMapping("/{id}")
	@PreAuthorize("@pms.hasPermission('coupon_cnbrand_view')")
	public R getById(@PathVariable("id") Long id) {
		return R.ok(cnBrandService.getById(id));
	}

	/**
	 * 新增品牌表
	 *
	 * @param cnBrandVo 品牌表
	 * @return R
	 */
	@ApiOperation(value = "新增品牌表", notes = "新增品牌表")
	@SysLog("新增品牌表")
	@PostMapping
//	@PreAuthorize("@pms.hasPermission('coupon_cnbrand_add')")
	public R save(@RequestBody CnBrandVo cnBrandVo) throws Exception {
		log.info("->新增品牌表:{}", JSONUtil.toJsonStr(cnBrandVo));
		return cnBrandService.insertBrand(cnBrandVo);
	}

	/**
	 * 修改品牌表
	 *
	 * @param cnBrandVo 品牌表
	 * @return R
	 */
	@ApiOperation(value = "修改品牌表", notes = "修改品牌表")
	@SysLog("修改品牌表")
	@PutMapping
//	@PreAuthorize("@pms.hasPermission('coupon_cnbrand_edit')")
	public R updateById(@RequestBody CnBrandVo cnBrandVo) throws Exception {
		log.info("->修改品牌表:{}", JSONUtil.toJsonStr(cnBrandVo));
		return cnBrandService.updateBrand(cnBrandVo);
	}

	/**
	 * 通过id删除品牌表
	 *
	 * @param id id
	 * @return R
	 */
	@ApiOperation(value = "通过id删除品牌表", notes = "通过id删除品牌表")
	@SysLog("通过id删除品牌表")
	@DeleteMapping("/{id}")
	@PreAuthorize("@pms.hasPermission('coupon_cnbrand_del')")
	public R removeById(@PathVariable Long id) {
		return R.ok(cnBrandService.removeById(id));
	}

	/**
	 * 获取标签
	 *
	 * @return
	 */
	@ApiOperation(value = "获取标签")
	@GetMapping("getLabel")
	public R getLabel() {
		QueryWrapper<CnLabel> queryWrapper = new QueryWrapper<>();
		return R.ok(cnLabelService.list(queryWrapper.lambda().eq(CnLabel::getShowFlag, StatusEnum.normal.getValue())));
	}

	@ApiOperation(value = "获取最后绑定的品牌根据登陆人id")
	@GetMapping("getByLoginId")
	public R getByLoginId() {
		return R.ok(cnBrandService.list(Wrappers.lambdaQuery(CnBrand.class)
				.eq(CnBrand::getLoginId, SecurityUtils.getUserId())
				.eq(CnBrand::getDisplay, 0)//是否展示0是1否
				.orderByDesc(CnBrand::getCreateTime))//最后绑定的品牌
				.get(0).getLogoUrl());
	}

	/**
	 * 是否展示
	 *
	 * @param id
	 * @return
	 */
	@ApiOperation(value = "是否展示")
	@GetMapping("exhibition")
	public R exhibition(Long id) {
		CnBrand cnBrand = cnBrandService.getById(id);
		UpdateWrapper<CnBrand> updateWrapper = new UpdateWrapper<>();
		if (cnBrand.getDisplay().equals(StatusEnum.normal.getValue())) {
			updateWrapper.lambda().set(CnBrand::getDisplay, StatusEnum.forbid.getValue());
		} else {
			updateWrapper.lambda().set(CnBrand::getDisplay, StatusEnum.normal.getValue());
		}
		updateWrapper.lambda().eq(CnBrand::getId, id);
		return R.ok(cnBrandService.update(updateWrapper));
	}

	/**
	 * 上传
	 *
	 * @param file
	 * @return
	 */
	@ApiOperation(value = "上传文件")
	@PostMapping("uploadFile")
	public R uploadFile(@RequestParam("file") MultipartFile file) {
		return R.ok(cnBrandService.uploadFile(file));
	}

	@PostMapping("getByCompanyId")
	public R<List<Long>> getByCompanyId(@RequestBody String companyId) {
		List<Long> loginIds = new ArrayList<>();
		List<Long> Ids = new ArrayList<>();
		List<CnBrand> list = cnBrandService.list(Wrappers.lambdaQuery(CnBrand.class).eq(CnBrand::getCompanyId, Long.valueOf(companyId)));
		if (list != null && list.size() > 0) {
			list.forEach(o -> {
				loginIds.add(o.getLoginId());
				Ids.add(o.getId());
			});
			List<CnShop> cnShops = cnShopService.list(Wrappers.lambdaQuery(CnShop.class).in(CnShop::getBrandId, Ids));
			if (cnShops != null && cnShops.size() > 0) {
				cnShops.forEach(o -> {
					loginIds.add(o.getLoginId());
				});
			}
		}
		return R.ok(loginIds);
	}

	@PostMapping("bindedBrandUserByLoginId")
	public R<BindedBrandUserByLoginIdVo> bindedBrandUserByLoginId() {
		BindedBrandUserByLoginIdVo vo = new BindedBrandUserByLoginIdVo();
		Long sjId = SecurityUtils.getSjId();
		vo.setConpanyId(sjId);
		List<Long> ids = new ArrayList<>();
		List<CnBrand> list = new CnBrand().selectList(Wrappers.lambdaQuery(CnBrand.class).eq(CnBrand::getCompanyId, sjId));
		for (CnBrand o : list) {
			if (o.getLoginId() != null) {
				ids.add(o.getLoginId());
			}
		}
		vo.setIds(ids);
		return R.ok(vo);
	}

	@PostMapping("getByLoginId")
	public R<List<Long>> getByLoginId(@RequestBody String loginId) {
/*		List<Long> loginIds = new ArrayList<>();
		List<Long> Ids = new ArrayList<>();
		List<CnBrand> list = cnBrandService.list(Wrappers.lambdaQuery(CnBrand.class).eq(CnBrand::getLoginId, Long.valueOf(loginId)));
		if (list != null && list.size() > 0) {
			list.forEach(o -> {
				loginIds.add(o.getLoginId());
				Ids.add(o.getId());
			});
			List<CnShop> cnShops = cnShopService.list(Wrappers.lambdaQuery(CnShop.class).eq(CnShop::getBrandId, loginId));
			if (cnShops != null && cnShops.size() > 0) {
				cnShops.forEach(o -> {
					loginIds.add(o.getLoginId());
				});
			}
		}*/
		List<CnShop> cnShops = cnShopService.list(Wrappers.lambdaQuery(CnShop.class).eq(CnShop::getBrandId, loginId));
		List<Long> loginIds = cnShops.stream().map(CnShop::getLoginId).collect(Collectors.toList());
		return R.ok(loginIds);
	}


	@ApiOperation(value = "根据登录人角色获取品牌", notes = "根据登录人角色获取品牌")
	@GetMapping("/getBrand")
	public R getBrand() {
		Integer userType = SecurityUtils.getUser().getUserType();
		Long sjId = SecurityUtils.getSjId();
		QueryWrapper<CnBrand> queryWrapper = new QueryWrapper<>();
		queryWrapper.lambda().eq(CnBrand::getDelFlag, 0);
		if (userType.equals(UserTypeEnum.company.getValue())) {
			queryWrapper.lambda().eq(CnBrand::getCompanyId, sjId);
		} else if (userType.equals(UserTypeEnum.brand.getValue())) {
			queryWrapper.lambda().eq(CnBrand::getLoginId, SecurityUtils.getUserId());
		}
		return R.ok(cnBrandService.list(queryWrapper));
	}


	/**
	 * 品牌上下架
	 *
	 * @param cnBrandVo 品牌表
	 * @return R
	 */
	@ApiOperation(value = "品牌上下架", notes = "品牌上下架")
	@SysLog("品牌上下架")
	@PostMapping("/updateByDisplay")
	public R updateByDisplay(@RequestBody CnBrandVo cnBrandVo) throws Exception {
		log.info("->品牌上下架:{}", JSONUtil.toJsonStr(cnBrandVo));
		return cnBrandService.updateByDisplay(cnBrandVo);
	}


	/**
	 * 根据品牌名称 获取品牌列表
	 *
	 * @param cnBrand 品牌表
	 * @return
	 */
	@ApiOperation(value = "根据品牌名称 获取品牌列表", notes = "根据品牌名称 获取品牌列表")
	@GetMapping("/getBrandList")
	public R getBrandList(CnBrand cnBrand) {
		log.info("->根据品牌名称 获取品牌列表:{}", JSONUtil.toJsonStr(cnBrand));
		QueryWrapper<CnBrand> queryWrapper = new QueryWrapper();
		queryWrapper.lambda().eq(CnBrand::getDisplay, DisplayEnum.usable.getValue())
				.like(!StringUtil.isEmpty(cnBrand.getBrandName()), CnBrand::getBrandName, cnBrand.getBrandName());
		List<CnBrand> brandList = cnBrandService.list(queryWrapper);
		if (null == brandList || brandList.size() == 0){
			return R.ok(null);
		}
		List<VBrandAgreement> brandAgreementList = remoteBrandAgreementService.getByBrandIdList(
				brandList.stream().map(CnBrand::getId).collect(Collectors.toList()));
		if (null != brandAgreementList && brandAgreementList.size() > 0){
			brandList.stream().forEach(itme -> {
				itme.setDelFlag(null);
				brandAgreementList.stream().forEach(agreement -> {
					if (itme.getId().equals(agreement.getBrandId())){
						itme.setDelFlag(2);
					}
				});
			});
		}
		return R.ok(brandList);
	}

	/**
	 * 根据品牌名称 获取品牌列表(分页)
	 *
	 * @param page  	分页
	 * @param cnBrand 品牌表
	 * @return
	 */
	@ApiOperation(value = "根据品牌名称 获取品牌列表(分页)", notes = "根据品牌名称 获取品牌列表(分页)")
	@GetMapping("/getBrandPage")
	public R getBrandPage(Page page, CnBrand cnBrand) {
		log.info("->根据品牌名称 获取品牌列表(分页):{}", page, JSONUtil.toJsonStr(cnBrand));
		IPage<CnBrand> brandList = cnBrandService.page(page, Wrappers.lambdaQuery(CnBrand.class)
				.eq(CnBrand::getDisplay, DisplayEnum.usable.getValue())
				.like(!StringUtil.isEmpty(cnBrand.getBrandName()), CnBrand::getBrandName, cnBrand.getBrandName()));
		return R.ok(brandList);
	}
	@ApiOperation(value = "根据条件获取门店列表")
	@GetMapping("/list")
	public R list( CnBrand cnBrand) {
		log.info("->获取品牌列表,{}",cnBrand);
		List<CnBrand> list = cnBrandService.list(Wrappers.query(cnBrand));
		return R.ok(list);
	}




}
